__author__ = 'shawhen'

import ctypes

from . import WinDef
from . import WinNT

from . import User32

from ...cstd import stddef

from .shared import minwindef as m_shared_minwindef


#
# ShowWindow() Commands
#
SW_HIDE             = 0
SW_SHOWNORMAL       = 1
SW_NORMAL           = 1
SW_SHOWMINIMIZED    = 2
SW_SHOWMAXIMIZED    = 3
SW_MAXIMIZE         = 3
SW_SHOWNOACTIVATE   = 4
SW_SHOW             = 5
SW_MINIMIZE         = 6
SW_SHOWMINNOACTIVE  = 7
SW_SHOWNA           = 8
SW_RESTORE          = 9
SW_SHOWDEFAULT      = 10
SW_FORCEMINIMIZE    = 11
SW_MAX              = 11


#
# Class styles
#
CS_VREDRAW          = 0x0001
CS_HREDRAW          = 0x0002
CS_DBLCLKS          = 0x0008
CS_OWNDC            = 0x0020
CS_CLASSDC          = 0x0040
CS_PARENTDC         = 0x0080
CS_NOCLOSE          = 0x0200
CS_SAVEBITS         = 0x0800
CS_BYTEALIGNCLIENT  = 0x1000
CS_BYTEALIGNWINDOW  = 0x2000
CS_GLOBALCLASS      = 0x4000

CS_IME              = 0x00010000
CS_DROPSHADOW       = 0x00020000

WNDPROC = ctypes.CFUNCTYPE(WinDef.LRESULT, WinDef.HWND, WinDef.UINT, WinDef.WPARAM, WinDef.LPARAM)

class WNDCLASSEX(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
        ("cbSize", WinDef.UINT),
        # Win 3.x
        ("style", WinDef.UINT),
        ("lpfnWndProc", WNDPROC),
        ("cbClsExtra", ctypes.c_int),
        ("cbWndExtra", ctypes.c_int),
        ("hInstance", WinDef.HINSTANCE),
        ("hIcon", WinDef.HICON),
        ("hCursor", WinDef.HCURSOR),
        ("hbrBackgroud", WinDef.HBRUSH),
        ("lpszMenuName", WinNT.LPCWSTR),
        ("lpszClassName", WinNT.LPCWSTR),
        # Win 4.x
        ("hIconSm", WinDef.HICON)
    ]


IDI_APPLICATION     = 32512
IDI_HAND            = 32513
IDI_QUESTION        = 32514
IDI_EXCLAMATION     = 32515
IDI_ASTERISK        = 32516

IDI_WARNING = IDI_EXCLAMATION
IDI_ERROR = IDI_HAND
IDI_INFORMATION = IDI_ASTERISK

IMAGE_BITMAP        = 0
IMAGE_ICON          = 1
IMAGE_CURSOR        = 2
IMAGE_ENHMETAFILE   = 3


LR_DEFAULTCOLOR     = 0x00000000
LR_MONOCHROME       = 0x00000001
LR_COLOR            = 0x00000002
LR_COPYRETURNORG    = 0x00000004
LR_COPYDELETEORG    = 0x00000008
LR_LOADFROMFILE     = 0x00000010
LR_LOADTRANSPARENT  = 0x00000020
LR_DEFAULTSIZE      = 0x00000040
LR_VGACOLOR         = 0x00000080
LR_LOADMAP3DCOLORS  = 0x00001000
LR_CREATEDIBSECTION = 0x00002000
LR_COPYFROMRESOURCE = 0x00004000
LR_SHARED           = 0x00008000

#
# Standard Cursor IDs
#
IDC_ARROW           = 32512
IDC_IBEAM           = 32513
IDC_WAIT            = 32514
IDC_CROSS           = 32515
IDC_UPARROW         = 32516
IDC_SIZENWSE        = 32642
IDC_SIZENESW        = 32643
IDC_SIZEWE          = 32644
IDC_SIZENS          = 32645
IDC_SIZEALL         = 32646
IDC_NO              = 32648 # not in win3.1
IDC_HAND            = 32649
IDC_APPSTARTING     = 32650 # not in win3.1
IDC_HELP            = 32651


def LoadImage(hInstance, image_name, image_type, width, height, fuLoad):
    """
    :param hInstance None<->NULL
    :return HANDLE
    """
    if hInstance is None:
        hInstance = stddef.NULL
    return User32.User32_dll.LoadImageW(hInstance, image_name, image_type, width, height, fuLoad)


def RegisterClassEx(wnd_class):
    return User32.User32_dll.RegisterClassExW(ctypes.byref(wnd_class))


#
# Window Styles
#
WS_OVERLAPPED       = 0x00000000
WS_POPUP            = 0x80000000
WS_CHILD            = 0x40000000
WS_MINIMIZE         = 0x20000000
WS_VISIBLE          = 0x10000000
WS_DISABLED         = 0x08000000
WS_CLIPSIBLINGS     = 0x04000000
WS_CLIPCHILDREN     = 0x02000000
WS_MAXIMIZE         = 0x01000000
WS_CAPTION          = 0x00C00000     # WS_BORDER | WS_DLGFRAME
WS_BORDER           = 0x00800000
WS_DLGFRAME         = 0x00400000
WS_VSCROLL          = 0x00200000
WS_HSCROLL          = 0x00100000
WS_SYSMENU          = 0x00080000
WS_THICKFRAME       = 0x00040000
WS_GROUP            = 0x00020000
WS_TABSTOP          = 0x00010000

WS_MINIMIZEBOX      = 0x00020000
WS_MAXIMIZEBOX      = 0x00010000

#
# Common Window Styles
#
WS_OVERLAPPEDWINDOW =       (WS_OVERLAPPED     | \
                             WS_CAPTION        | \
                             WS_SYSMENU        | \
                             WS_THICKFRAME     | \
                             WS_MINIMIZEBOX    | \
                             WS_MAXIMIZEBOX)

WS_TILED            = WS_OVERLAPPED
WS_ICONIC           = WS_MINIMIZE
WS_SIZEBOX          = WS_THICKFRAME
WS_TILEDWINDOW      = WS_OVERLAPPEDWINDOW

CW_USEDEFAULT        = 0x80000000

def CreateWindowEx(ex_style, class_name, window_name, style, x, y, width, height, hWndParent, hMenu, hInstance, lpParam):
    """
    :param hWndParent None<->NULL
    :param hMenu None<->NULL
    :param lpParam None<->NULL
    :return HWND
    """
    from . import WinDef

    dwExStyle = WinDef.DWORD(ex_style)
    dwStyle = WinDef.DWORD(style)

    if hWndParent is None:
        hWndParent = stddef.NULL
    if hMenu is None:
        hMenu = stddef.NULL
    if lpParam is None:
        lpParam = stddef.NULL

    return User32.User32_dll.CreateWindowExW(dwExStyle, class_name, window_name, dwStyle, x, y, width, height,
                                             hWndParent, hMenu, hInstance, lpParam)



def ShowWindow(hWnd, show_flag):
    return User32.User32_dll.ShowWindow(hWnd, show_flag)


def UpdateWindow(hWnd):
    return User32.User32_dll.UpdateWindow(hWnd)


# Message Struct
class MSG(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
        ("hwnd", WinDef.HWND),
        ("message", WinDef.UINT),
        ("wParam", WinDef.WPARAM),
        ("lParam", WinDef.LPARAM),
        ("time", WinDef.DWORD),
        ("pt", WinDef.POINT)
    ]

#
# Window Messages
#

WM_NULL                         = 0x0000
WM_CREATE                       = 0x0001
WM_DESTROY                      = 0x0002
WM_MOVE                         = 0x0003
WM_SIZE                         = 0x0005

WM_ACTIVATE                     = 0x0006
#
# WM_ACTIVATE state values
#
WA_INACTIVE     = 0
WA_ACTIVE       = 1
WA_CLICKACTIVE  = 2

WM_SETFOCUS                     = 0x0007
WM_KILLFOCUS                    = 0x0008
WM_ENABLE                       = 0x000A
WM_SETREDRAW                    = 0x000B
WM_SETTEXT                      = 0x000C
WM_GETTEXT                      = 0x000D
WM_GETTEXTLENGTH                = 0x000E
WM_PAINT                        = 0x000F
WM_CLOSE                        = 0x0010

WM_QUERYENDSESSION              = 0x0011
WM_QUERYOPEN                    = 0x0013
WM_ENDSESSION                   = 0x0016

WM_QUIT                         = 0x0012
WM_ERASEBKGND                   = 0x0014
WM_SYSCOLORCHANGE               = 0x0015
WM_SHOWWINDOW                   = 0x0018
WM_WININICHANGE                 = 0x001A

WM_SETTINGCHANGE                = WM_WININICHANGE


WM_DEVMODECHANGE                = 0x001B
WM_ACTIVATEAPP                  = 0x001C
WM_FONTCHANGE                   = 0x001D
WM_TIMECHANGE                   = 0x001E
WM_CANCELMODE                   = 0x001F
WM_SETCURSOR                    = 0x0020
WM_MOUSEACTIVATE                = 0x0021
WM_CHILDACTIVATE                = 0x0022
WM_QUEUESYNC                    = 0x0023

WM_GETMINMAXINFO                = 0x0024


#if(WINVER >= 0x0400)
WM_NOTIFY                       = 0x004E
WM_INPUTLANGCHANGEREQUEST       = 0x0050
WM_INPUTLANGCHANGE              = 0x0051
WM_TCARD                        = 0x0052
WM_HELP                         = 0x0053
WM_USERCHANGED                  = 0x0054
WM_NOTIFYFORMAT                 = 0x0055

NFR_ANSI                            = 1
NFR_UNICODE                         = 2
NF_QUERY                            = 3
NF_REQUERY                          = 4

WM_CONTEXTMENU                  = 0x007B
WM_STYLECHANGING                = 0x007C
WM_STYLECHANGED                 = 0x007D
WM_DISPLAYCHANGE                = 0x007E
WM_GETICON                      = 0x007F
WM_SETICON                      = 0x0080
#endif /* WINVER >= 0x0400 */

WM_NCCREATE                     = 0x0081
WM_NCDESTROY                    = 0x0082
WM_NCCALCSIZE                   = 0x0083
WM_NCHITTEST                    = 0x0084
WM_NCPAINT                      = 0x0085
WM_NCACTIVATE                   = 0x0086
WM_GETDLGCODE                   = 0x0087
#ifndef _WIN32_WCE
WM_SYNCPAINT                    = 0x0088
#endif
WM_NCMOUSEMOVE                  = 0x00A0
WM_NCLBUTTONDOWN                = 0x00A1
WM_NCLBUTTONUP                  = 0x00A2
WM_NCLBUTTONDBLCLK              = 0x00A3
WM_NCRBUTTONDOWN                = 0x00A4
WM_NCRBUTTONUP                  = 0x00A5
WM_NCRBUTTONDBLCLK              = 0x00A6
WM_NCMBUTTONDOWN                = 0x00A7
WM_NCMBUTTONUP                  = 0x00A8
WM_NCMBUTTONDBLCLK              = 0x00A9



#if(_WIN32_WINNT >= 0x0500)
WM_NCXBUTTONDOWN                = 0x00AB
WM_NCXBUTTONUP                  = 0x00AC
WM_NCXBUTTONDBLCLK              = 0x00AD
#endif /* _WIN32_WINNT >= 0x0500 */


#if(_WIN32_WINNT >= 0x0501)
WM_INPUT_DEVICE_CHANGE          = 0x00FE
#endif /* _WIN32_WINNT >= 0x0501 */

#if(_WIN32_WINNT >= 0x0501)
WM_INPUT                        = 0x00FF
#endif /* _WIN32_WINNT >= 0x0501 */

WM_KEYFIRST                     = 0x0100
WM_KEYDOWN                      = 0x0100
WM_KEYUP                        = 0x0101
WM_CHAR                         = 0x0102
WM_DEADCHAR                     = 0x0103
WM_SYSKEYDOWN                   = 0x0104
WM_SYSKEYUP                     = 0x0105
WM_SYSCHAR                      = 0x0106
WM_SYSDEADCHAR                  = 0x0107
#if(_WIN32_WINNT >= 0x0501)
WM_UNICHAR                      = 0x0109
WM_KEYLAST                      = 0x0109
UNICODE_NOCHAR                  = 0xFFFF
#else
WM_KEYLAST                      = 0x0108
#endif /* _WIN32_WINNT >= 0x0501 */

#if(WINVER >= 0x0400)
WM_IME_STARTCOMPOSITION         = 0x010D
WM_IME_ENDCOMPOSITION           = 0x010E
WM_IME_COMPOSITION              = 0x010F
WM_IME_KEYLAST                  = 0x010F
#endif /* WINVER >= 0x0400 */

WM_INITDIALOG                   = 0x0110
WM_COMMAND                      = 0x0111
WM_SYSCOMMAND                   = 0x0112
WM_TIMER                        = 0x0113
WM_HSCROLL                      = 0x0114
WM_VSCROLL                      = 0x0115
WM_INITMENU                     = 0x0116
WM_INITMENUPOPUP                = 0x0117
#if(WINVER >= 0x0601)
WM_GESTURE                      = 0x0119
WM_GESTURENOTIFY                = 0x011A
#endif /* WINVER >= 0x0601 */
WM_MENUSELECT                   = 0x011F
WM_MENUCHAR                     = 0x0120
WM_ENTERIDLE                    = 0x0121
#if(WINVER >= 0x0500)
#ifndef _WIN32_WCE
WM_MENURBUTTONUP                = 0x0122
WM_MENUDRAG                     = 0x0123
WM_MENUGETOBJECT                = 0x0124
WM_UNINITMENUPOPUP              = 0x0125
WM_MENUCOMMAND                  = 0x0126

#ifndef _WIN32_WCE
#if(_WIN32_WINNT >= 0x0500)
WM_CHANGEUISTATE                = 0x0127
WM_UPDATEUISTATE                = 0x0128
WM_QUERYUISTATE                 = 0x0129


#
# Button Control Messages
#
BM_GETCHECK        = 0x00F0
BM_SETCHECK        = 0x00F1
BM_GETSTATE        = 0x00F2
BM_SETSTATE        = 0x00F3
BM_SETSTYLE        = 0x00F4

BM_CLICK           = 0x00F5
BM_GETIMAGE        = 0x00F6
BM_SETIMAGE        = 0x00F7

BM_SETDONTCLICK    = 0x00F8


#/*
# * Virtual Keys, Standard Set
# */
VK_LBUTTON        = 0x01
VK_RBUTTON        = 0x02
VK_CANCEL         = 0x03
VK_MBUTTON        = 0x04    #/* NOT contiguous with L & RBUTTON */

#if(_WIN32_WINNT >= = 0x0500)
VK_XBUTTON1       = 0x05    #/* NOT contiguous with L & RBUTTON */
VK_XBUTTON2       = 0x06    #/* NOT contiguous with L & RBUTTON */
#endif /* _WIN32_WINNT >= = 0x0500 */

#/*
# * = 0x07 : unassigned
# */

VK_BACK           = 0x08
VK_TAB            = 0x09

#/*
# * = 0x0A - = 0x0B : reserved
# */

VK_CLEAR          = 0x0C
VK_RETURN         = 0x0D

VK_SHIFT          = 0x10
VK_CONTROL        = 0x11
VK_MENU           = 0x12
VK_PAUSE          = 0x13
VK_CAPITAL        = 0x14

VK_KANA           = 0x15
VK_HANGEUL        = 0x15  #/* old name - should be here for compatibility */
VK_HANGUL         = 0x15
VK_JUNJA          = 0x17
VK_FINAL          = 0x18
VK_HANJA          = 0x19
VK_KANJI          = 0x19

VK_ESCAPE         = 0x1B

VK_CONVERT        = 0x1C
VK_NONCONVERT     = 0x1D
VK_ACCEPT         = 0x1E
VK_MODECHANGE     = 0x1F

VK_SPACE          = 0x20
VK_PRIOR          = 0x21
VK_NEXT           = 0x22
VK_END            = 0x23
VK_HOME           = 0x24
VK_LEFT           = 0x25
VK_UP             = 0x26
VK_RIGHT          = 0x27
VK_DOWN           = 0x28
VK_SELECT         = 0x29
VK_PRINT          = 0x2A
VK_EXECUTE        = 0x2B
VK_SNAPSHOT       = 0x2C
VK_INSERT         = 0x2D
VK_DELETE         = 0x2E
VK_HELP           = 0x2F

#/*
# * VK_0 - VK_9 are the same as ASCII '0' - '9' (= 0x30 - = 0x39)
# * = 0x40 : unassigned
# * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (= 0x41 - = 0x5A)
# */

VK_LWIN           = 0x5B
VK_RWIN           = 0x5C
VK_APPS           = 0x5D

#/*
# * = 0x5E : reserved
# */

VK_SLEEP          = 0x5F

VK_NUMPAD0        = 0x60
VK_NUMPAD1        = 0x61
VK_NUMPAD2        = 0x62
VK_NUMPAD3        = 0x63
VK_NUMPAD4        = 0x64
VK_NUMPAD5        = 0x65
VK_NUMPAD6        = 0x66
VK_NUMPAD7        = 0x67
VK_NUMPAD8        = 0x68
VK_NUMPAD9        = 0x69
VK_MULTIPLY       = 0x6A
VK_ADD            = 0x6B
VK_SEPARATOR      = 0x6C
VK_SUBTRACT       = 0x6D
VK_DECIMAL        = 0x6E
VK_DIVIDE         = 0x6F
VK_F1             = 0x70
VK_F2             = 0x71
VK_F3             = 0x72
VK_F4             = 0x73
VK_F5             = 0x74
VK_F6             = 0x75
VK_F7             = 0x76
VK_F8             = 0x77
VK_F9             = 0x78
VK_F10            = 0x79
VK_F11            = 0x7A
VK_F12            = 0x7B
VK_F13            = 0x7C
VK_F14            = 0x7D
VK_F15            = 0x7E
VK_F16            = 0x7F
VK_F17            = 0x80
VK_F18            = 0x81
VK_F19            = 0x82
VK_F20            = 0x83
VK_F21            = 0x84
VK_F22            = 0x85
VK_F23            = 0x86
VK_F24            = 0x87

#/*
# * = 0x88 - = 0x8F : unassigned
# */

VK_NUMLOCK        = 0x90
VK_SCROLL         = 0x91

#/*
# * NEC PC-9800 kbd definitions
# */
VK_OEM_NEC_EQUAL  = 0x92   #// '=' key on numpad

#/*
# * Fujitsu/OASYS kbd definitions
# */
VK_OEM_FJ_JISHO   = 0x92   #// 'Dictionary' key
VK_OEM_FJ_MASSHOU = 0x93   #// 'Unregister word' key
VK_OEM_FJ_TOUROKU = 0x94   #// 'Register word' key
VK_OEM_FJ_LOYA    = 0x95   #// 'Left OYAYUBI' key
VK_OEM_FJ_ROYA    = 0x96   #// 'Right OYAYUBI' key

#/*
# * = 0x97 - = 0x9F : unassigned
# */

#/*
# * VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys.
# * Used only as parameters to GetAsyncKeyState() and GetKeyState().
# * No other API or message will distinguish left and right keys in this way.
# */
VK_LSHIFT         = 0xA0
VK_RSHIFT         = 0xA1
VK_LCONTROL       = 0xA2
VK_RCONTROL       = 0xA3
VK_LMENU          = 0xA4
VK_RMENU          = 0xA5

#if(_WIN32_WINNT >= = = 0x0500)
VK_BROWSER_BACK        = 0xA6
VK_BROWSER_FORWARD     = 0xA7
VK_BROWSER_REFRESH     = 0xA8
VK_BROWSER_STOP        = 0xA9
VK_BROWSER_SEARCH      = 0xAA
VK_BROWSER_FAVORITES   = 0xAB
VK_BROWSER_HOME        = 0xAC

VK_VOLUME_MUTE         = 0xAD
VK_VOLUME_DOWN         = 0xAE
VK_VOLUME_UP           = 0xAF
VK_MEDIA_NEXT_TRACK    = 0xB0
VK_MEDIA_PREV_TRACK    = 0xB1
VK_MEDIA_STOP          = 0xB2
VK_MEDIA_PLAY_PAUSE    = 0xB3
VK_LAUNCH_MAIL         = 0xB4
VK_LAUNCH_MEDIA_SELECT = 0xB5
VK_LAUNCH_APP1         = 0xB6
VK_LAUNCH_APP2         = 0xB7

#endif /* _WIN32_WINNT >= = = 0x0500 */

#/*
# * = 0xB8 - = 0xB9 : reserved
# */

VK_OEM_1          = 0xBA   #// ';:' for US
VK_OEM_PLUS       = 0xBB   #// '+' any country
VK_OEM_COMMA      = 0xBC   #// ',' any country
VK_OEM_MINUS      = 0xBD   #// '-' any country
VK_OEM_PERIOD     = 0xBE   #// '.' any country
VK_OEM_2          = 0xBF   #// '/?' for US
VK_OEM_3          = 0xC0   #// '`~' for US

#/*
# * = 0xC1 - = 0xD7 : reserved
# */

#/*
# * = 0xD8 - = 0xDA : unassigned
# */

VK_OEM_4          = 0xDB  #//  '[{' for US
VK_OEM_5          = 0xDC  #//  '\|' for US
VK_OEM_6          = 0xDD  #//  ']}' for US
VK_OEM_7          = 0xDE  #//  ''"' for US
VK_OEM_8          = 0xDF

#/*
# * = 0xE0 : reserved
# */

#/*
# * Various extended or enhanced keyboards
# */
VK_OEM_AX         = 0xE1  #//  'AX' key on Japanese AX kbd
VK_OEM_102        = 0xE2  #//  "<>" or "\|" on RT 102-key kbd.
VK_ICO_HELP       = 0xE3  #//  Help key on ICO
VK_ICO_00         = 0xE4  #//  00 key on ICO

#if(WINVER >= = 0x0400)
VK_PROCESSKEY     = 0xE5
#endif /* WINVER >= = 0x0400 */

VK_ICO_CLEAR      = 0xE6


#if(_WIN32_WINNT >= = 0x0500)
VK_PACKET         = 0xE7
#endif /* _WIN32_WINNT >= = 0x0500 */

#/*
# * = 0xE8 : unassigned
# */

#
# Nokia/Ericsson definitions
#
VK_OEM_RESET      = 0xE9
VK_OEM_JUMP       = 0xEA
VK_OEM_PA1        = 0xEB
VK_OEM_PA2        = 0xEC
VK_OEM_PA3        = 0xED
VK_OEM_WSCTRL     = 0xEE
VK_OEM_CUSEL      = 0xEF
VK_OEM_ATTN       = 0xF0
VK_OEM_FINISH     = 0xF1
VK_OEM_COPY       = 0xF2
VK_OEM_AUTO       = 0xF3
VK_OEM_ENLW       = 0xF4
VK_OEM_BACKTAB    = 0xF5

VK_ATTN           = 0xF6
VK_CRSEL          = 0xF7
VK_EXSEL          = 0xF8
VK_EREOF          = 0xF9
VK_PLAY           = 0xFA
VK_ZOOM           = 0xFB
VK_NONAME         = 0xFC
VK_PA1            = 0xFD
VK_OEM_CLEAR      = 0xFE


def GetMessage(msg, hWnd, msg_filter_min, msg_filter_max):
    """
    :param hWnd None<->NULL
    :return True/False
    """
    if hWnd is None:
        hWnd = stddef.NULL
    wMsgFilterMin = WinDef.UINT(msg_filter_min)
    wMsgFilterMax = WinDef.UINT(msg_filter_max)

    result = User32.User32_dll.GetMessageW(ctypes.byref(msg), hWnd, wMsgFilterMin, wMsgFilterMax)
    if result == WinDef.TRUE:
        return True
    elif result == WinDef.FALSE:
        return False


def TranslateMessage(msg):
    """
    :return True/False
    """
    result = User32.User32_dll.TranslateMessage(ctypes.byref(msg))
    if result == WinDef.TRUE:
        return True
    elif result == WinDef.FALSE:
        return False


def DispatchMessage(msg):
    return User32.User32_dll.DispatchMessageW(ctypes.byref(msg))


def PostQuitMessage(exit_code):
    User32.User32_dll.PostQuitMessage(exit_code)



def DefWindowProc(hWnd, msg, wParam, lParam):
    return User32.User32_dll.DefWindowProcW(hWnd, msg, wParam, lParam)


def WaitForInputIdle(hProcess, milliseconds):
    """
    :return DWORD
    """
    dwMilliseconds = m_shared_minwindef.DWORD(milliseconds)

    return User32.User32_dll.WaitForInputIdle(hProcess, dwMilliseconds)


WNDENUMPROC = ctypes.CFUNCTYPE(m_shared_minwindef.BOOL,
                               WinDef.HWND, WinDef.LPARAM)

def EnumWindows(enum_cb, arg):
    """
    :return True/False
    """
    lpEnumFunc = WNDENUMPROC(enum_cb)
    lParam = WinDef.LPARAM(arg)

    result = True
    try:
        result = User32.User32_dll.EnumWindows(lpEnumFunc, lParam)
    except ValueError as e:
        if "byts missing" in str(e):  # sorry, i have no idea...
            result = True
            return result
    if result == m_shared_minwindef.FALSE:
        result = False
    else:
        result = True
    return result


def GetWindowThreadProcessId(hWnd):
    """
    :return (Thread Id, Process Id)
    """
    dwProcessId = m_shared_minwindef.DWORD(0)

    thread_id = User32.User32_dll.GetWindowThreadProcessId(hWnd, ctypes.byref(dwProcessId))
    return (thread_id, dwProcessId.value)


def SendMessage(hWnd, msg, w_param=None, l_param=None):
    """
    :param w_param None<->NULL
    :param l_param None<->NULL
    :return LRESULT
    """
    Msg = m_shared_minwindef.UINT(msg)

    if w_param is None:
        w_param = stddef.NULL
    if l_param is None:
        l_param = stddef.NULL
    wParam = m_shared_minwindef.WPARAM(w_param)
    lParam = m_shared_minwindef.LPARAM(l_param)

    result = User32.User32_dll.SendMessageW(hWnd, Msg, wParam, lParam)
    return result